from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.db.models import Q, Count, Sum
from django.utils import timezone
from django.http import FileResponse, Http404
from django.views import View
from .models import DockerServer, DockerRegistry
from .serializers import (
    DockerServerSerializer, DockerServerListSerializer, DockerServerTestConnectionSerializer,
    DockerRegistrySerializer, DockerRegistryListSerializer, DockerStatisticsSerializer
)
from .harbor_service import HarborAPIService
from .services import DockerService, test_docker_connection
import logging

logger = logging.getLogger(__name__)


def decode_image_id(encoded_id):
    """解码Base64编码的镜像ID"""
    import base64
    # 恢复base64填充
    padded_id = encoded_id + '=' * (4 - len(encoded_id) % 4)
    # 恢复base64字符
    padded_id = padded_id.replace('-', '+').replace('_', '/')
    return base64.b64decode(padded_id).decode('utf-8')


class DockerServerViewSet(viewsets.ModelViewSet):
    """Docker服务器管理ViewSet"""
    queryset = DockerServer.objects.all()
    permission_classes = [IsAuthenticated]

    def get_serializer_class(self):
        if self.action == 'list':
            return DockerServerListSerializer
        return DockerServerSerializer

    def get_queryset(self):
        queryset = DockerServer.objects.all()

        # 搜索过滤
        search = self.request.query_params.get('search', None)
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) |
                Q(host__icontains=search) |
                Q(description__icontains=search)
            )

        # 状态过滤
        status_filter = self.request.query_params.get('status', None)
        if status_filter:
            queryset = queryset.filter(connection_status=status_filter)

        # 是否启用过滤
        is_active = self.request.query_params.get('is_active', None)
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == 'true')

        return queryset.order_by('-is_default', '-created_at')

    @action(detail=True, methods=['post'])
    def test_connection(self, request, pk=None):
        """测试单个服务器连接"""
        try:
            docker_server = self.get_object()
            docker_service = DockerService(docker_server)
            result = docker_service.test_connection()

            return Response(result)

        except Exception as e:
            logger.error(f"测试连接失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'测试连接失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['post'])
    def test_connection_config(self, request):
        """测试连接配置（不保存到数据库）"""
        try:
            serializer = DockerServerTestConnectionSerializer(data=request.data)
            if serializer.is_valid():
                data = serializer.validated_data
                result = test_docker_connection(
                    host=data['host'],
                    ssh_port=data['ssh_port'],
                    ssh_username=data['ssh_username'],
                    ssh_password=data['ssh_password'],
                    ssh_key_path=data.get('ssh_key_path')
                )
                return Response(result)
            else:
                return Response({
                    'success': False,
                    'message': '参数验证失败',
                    'errors': serializer.errors
                }, status=status.HTTP_400_BAD_REQUEST)

        except Exception as e:
            logger.error(f"测试连接配置失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'测试连接失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['post'])
    def test_all_connections(self, request):
        """测试所有服务器连接"""
        try:
            servers = DockerServer.objects.filter(is_active=True)
            results = []

            for server in servers:
                docker_service = DockerService(server)
                result = docker_service.test_connection()
                results.append({
                    'server_id': server.id,
                    'server_name': server.name,
                    'result': result
                })

            return Response({
                'success': True,
                'results': results
            })

        except Exception as e:
            logger.error(f"批量测试连接失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'批量测试失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def sync_info(self, request, pk=None):
        """同步服务器信息"""
        try:
            docker_server = self.get_object()
            docker_service = DockerService(docker_server)

            # 更新统计信息
            if docker_service.update_statistics():
                # 获取系统信息
                system_info = docker_service.get_system_info()

                return Response({
                    'success': True,
                    'message': '服务器信息同步成功',
                    'system_info': system_info
                })
            else:
                return Response({
                    'success': False,
                    'message': '服务器信息同步失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except Exception as e:
            logger.error(f"同步服务器信息失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'同步失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['get'])
    def statistics(self, request):
        """获取Docker服务器统计信息"""
        try:
            # 基础统计
            total_servers = DockerServer.objects.count()
            active_servers = DockerServer.objects.filter(is_active=True).count()
            connected_servers = DockerServer.objects.filter(
                connection_status='connected',
                is_active=True
            ).count()

            # 聚合统计
            aggregated_stats = DockerServer.objects.filter(
                is_active=True,
                connection_status='connected'
            ).aggregate(
                total_containers=Sum('total_containers'),
                running_containers=Sum('running_containers'),
                total_images=Sum('total_images'),
                total_volumes=Sum('total_volumes'),
                total_networks=Sum('total_networks')
            )

            # 镜像仓库统计
            total_registries = DockerRegistry.objects.count()
            connected_registries = DockerRegistry.objects.filter(
                connection_status='connected',
                is_active=True
            ).count()

            statistics_data = {
                'total_docker_servers': total_servers,
                'connected_servers': connected_servers,
                'total_containers': aggregated_stats['total_containers'] or 0,
                'running_containers': aggregated_stats['running_containers'] or 0,
                'total_images': aggregated_stats['total_images'] or 0,
                'total_volumes': aggregated_stats['total_volumes'] or 0,
                'total_networks': aggregated_stats['total_networks'] or 0,
                'total_registries': total_registries,
                'connected_registries': connected_registries
            }

            serializer = DockerStatisticsSerializer(statistics_data)
            return Response(serializer.data)

        except Exception as e:
            logger.error(f"获取统计信息失败: {str(e)}")
            return Response({
                'error': f'获取统计信息失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='push_to_harbor')
    def push_to_harbor(self, request, pk=None):
        """推送镜像到Harbor"""
        print(f"🔥 收到推送请求: server_id={pk}, data={request.data}")
        logger.info(f"收到推送请求: server_id={pk}, data={request.data}")
        try:
            docker_server = DockerServer.objects.get(pk=pk, is_active=True)
            print(f"🔥 找到Docker服务器: {docker_server.name}")
            logger.info(f"找到Docker服务器: {docker_server.name}")
            docker_service = DockerService(docker_server)

            source_image = request.data.get('source_image')
            target_image = request.data.get('target_image')
            harbor_registry_id = request.data.get('harbor_registry_id')

            if not source_image or not target_image:
                return Response({
                    'success': False,
                    'message': '源镜像和目标镜像不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 获取Harbor仓库认证信息
            try:
                harbor_registry = DockerRegistry.objects.get(pk=harbor_registry_id, registry_type='harbor')
            except DockerRegistry.DoesNotExist:
                return Response({
                    'success': False,
                    'message': 'Harbor仓库不存在'
                }, status=status.HTTP_404_NOT_FOUND)

            # 推送镜像到Harbor
            result = docker_service.push_image_to_harbor(
                source_image,
                target_image,
                harbor_registry.url,
                harbor_registry.username,
                harbor_registry.password
            )

            if result['success']:
                return Response({
                    'success': True,
                    'message': '镜像推送成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '推送镜像失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            print(f"🔥 推送镜像异常: {str(e)}")
            import traceback
            print(f"🔥 异常堆栈: {traceback.format_exc()}")
            logger.error(f"推送镜像异常: {str(e)}", exc_info=True)
            return Response({
                'success': False,
                'message': f'推送镜像失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class DockerContainerViewSet(viewsets.ViewSet):
    """Docker容器管理ViewSet"""
    permission_classes = [IsAuthenticated]

    def list(self, request, server_pk=None):
        """获取容器列表"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            # 获取所有容器还是只获取运行中的容器
            all_containers = request.query_params.get('all', 'true').lower() == 'true'
            result = docker_service.get_containers(all_containers=all_containers)

            if result['success']:
                return Response({
                    'success': True,
                    'containers': result['containers']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取容器列表失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取容器列表失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取容器列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def start(self, request, server_pk=None, pk=None):
        """启动容器"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.start_container(pk)

            if result['success']:
                return Response({
                    'success': True,
                    'message': f'容器 {pk} 启动成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '启动容器失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"启动容器失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'启动容器失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def stop(self, request, server_pk=None, pk=None):
        """停止容器"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.stop_container(pk)

            if result['success']:
                return Response({
                    'success': True,
                    'message': f'容器 {pk} 停止成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '停止容器失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"停止容器失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'停止容器失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def restart(self, request, server_pk=None, pk=None):
        """重启容器"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.restart_container(pk)

            if result['success']:
                return Response({
                    'success': True,
                    'message': f'容器 {pk} 重启成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '重启容器失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"重启容器失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'重启容器失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def remove(self, request, server_pk=None, pk=None):
        """删除容器"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            force = request.data.get('force', False)
            result = docker_service.remove_container(pk, force=force)

            if result['success']:
                return Response({
                    'success': True,
                    'message': f'容器 {pk} 删除成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '删除容器失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"删除容器失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'删除容器失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def logs(self, request, server_pk=None, pk=None):
        """获取容器日志"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            # 获取日志行数参数，默认100行
            lines = request.query_params.get('lines', 100)
            try:
                lines = int(lines)
            except ValueError:
                lines = 100

            result = docker_service.get_container_logs(pk, lines=lines)

            if result['success']:
                return Response({
                    'success': True,
                    'logs': result['logs']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取容器日志失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取容器日志失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取容器日志失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def inspect(self, request, server_pk=None, pk=None):
        """获取容器详细信息"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.inspect_container(pk)

            if result['success']:
                return Response({
                    'success': True,
                    'data': result['data']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取容器详细信息失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取容器详细信息失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取容器详细信息失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['post'])
    def prune(self, request, server_pk=None):
        """清理停止的容器"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.prune_containers()

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message'],
                    'deleted_containers': result.get('deleted_containers', []),
                    'space_reclaimed': result.get('space_reclaimed', 0)
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '清理容器失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"清理容器失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'清理容器失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class DockerImageViewSet(viewsets.ViewSet):
    """Docker镜像管理ViewSet"""
    permission_classes = [IsAuthenticated]

    def list(self, request, server_pk=None):
        """获取镜像列表"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.get_images()

            if result['success']:
                return Response({
                    'success': True,
                    'images': result['images']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取镜像列表失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取镜像列表失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取镜像列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def remove(self, request, server_pk=None, pk=None):
        """删除镜像"""
        try:
            image_id = decode_image_id(pk)

            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            force = request.data.get('force', False)
            result = docker_service.remove_image(image_id, force=force)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '删除镜像失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"删除镜像失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'删除镜像失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['post'])
    def pull(self, request, server_pk=None):
        """拉取镜像"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            image_name = request.data.get('image_name')
            harbor_registry_id = request.data.get('harbor_registry_id')

            if not image_name:
                return Response({
                    'success': False,
                    'message': '镜像名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 如果是Harbor镜像，获取认证信息
            registry_info = None
            if harbor_registry_id:
                try:
                    harbor_registry = DockerRegistry.objects.get(pk=harbor_registry_id, registry_type='harbor')
                    registry_info = {
                        'url': harbor_registry.url,
                        'username': harbor_registry.username,
                        'password': harbor_registry.password
                    }
                except DockerRegistry.DoesNotExist:
                    logger.warning(f"Harbor仓库不存在: {harbor_registry_id}")

            result = docker_service.pull_image(image_name, registry_info)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '拉取镜像失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"拉取镜像失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'拉取镜像失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def tag(self, request, server_pk=None, pk=None):
        """为镜像添加标签"""
        try:
            image_id = decode_image_id(pk)

            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            target_image = request.data.get('target_image')
            if not target_image:
                return Response({
                    'success': False,
                    'message': '目标镜像名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            result = docker_service.tag_image(image_id, target_image)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '添加镜像标签失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"添加镜像标签失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'添加镜像标签失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def export(self, request, server_pk=None, pk=None):
        """导出镜像"""
        try:
            image_id = decode_image_id(pk)

            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            output_file = request.data.get('output_file')
            if not output_file:
                # 生成默认文件名
                output_file = f'/tmp/{pk.replace(":", "_")}.tar'

            result = docker_service.export_image(image_id, output_file)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message'],
                    'output_file': output_file
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '导出镜像失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"导出镜像失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'导出镜像失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path='inspect')
    def inspect(self, request, server_pk=None, pk=None):
        """获取镜像详细信息"""
        try:
            image_id = decode_image_id(pk)

            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.inspect_image(image_id)

            if result['success']:
                return Response({
                    'success': True,
                    'data': result['data']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取镜像详细信息失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取镜像详细信息失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取镜像详细信息失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def download(self, request, server_pk=None, pk=None):
        """下载镜像到本地"""
        try:
            image_id = decode_image_id(pk)

            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            # 生成临时文件名
            import tempfile
            import os
            temp_dir = tempfile.gettempdir()
            # 使用真实的镜像名生成文件名
            safe_image_name = image_id.replace(':', '_').replace('/', '_')
            temp_file = os.path.join(temp_dir, f'{safe_image_name}.tar')

            result = docker_service.export_image_for_download(image_id, temp_file)

            if result['success']:
                # 检查文件是否存在
                if os.path.exists(temp_file):
                    # 返回下载URL（这里需要配置静态文件服务）
                    download_url = f'/api/docker/download/{os.path.basename(temp_file)}'

                    return Response({
                        'success': True,
                        'download_url': download_url,
                        'filename': f'{safe_image_name}.tar',
                        'original_image': image_id
                    })
                else:
                    return Response({
                        'success': False,
                        'message': '导出文件不存在'
                    }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '导出镜像失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"下载镜像失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'下载镜像失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class DockerNetworkViewSet(viewsets.ViewSet):
    """Docker网络管理ViewSet"""
    permission_classes = [IsAuthenticated]

    def list(self, request, server_pk=None):
        """获取网络列表"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.get_networks()

            if result['success']:
                return Response({
                    'success': True,
                    'networks': result['networks']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取网络列表失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取网络列表失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取网络列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def create(self, request, server_pk=None):
        """创建网络"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            network_name = request.data.get('name')
            driver = request.data.get('driver', 'bridge')
            subnet = request.data.get('subnet')
            gateway = request.data.get('gateway')
            ip_range = request.data.get('ip_range')
            labels = request.data.get('labels', {})
            options = request.data.get('options', {})

            if not network_name:
                return Response({
                    'success': False,
                    'message': '网络名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            result = docker_service.create_network(
                name=network_name,
                driver=driver,
                subnet=subnet,
                gateway=gateway,
                ip_range=ip_range,
                labels=labels,
                options=options
            )

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message'],
                    'network_id': result.get('network_id')
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '创建网络失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"创建网络失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'创建网络失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def remove(self, request, server_pk=None, pk=None):
        """删除网络"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.remove_network(pk)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '删除网络失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"删除网络失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'删除网络失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class DockerVolumeViewSet(viewsets.ViewSet):
    """Docker数据卷管理ViewSet"""
    permission_classes = [IsAuthenticated]

    def list(self, request, server_pk=None):
        """获取数据卷列表"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.get_volumes()

            if result['success']:
                return Response({
                    'success': True,
                    'volumes': result['volumes']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取数据卷列表失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取数据卷列表失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取数据卷列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def create(self, request, server_pk=None):
        """创建数据卷"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            volume_name = request.data.get('name')
            driver = request.data.get('driver', 'local')
            labels = request.data.get('labels', {})
            options = request.data.get('options', {})

            if not volume_name:
                return Response({
                    'success': False,
                    'message': '数据卷名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            result = docker_service.create_volume(volume_name, driver, labels, options)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '创建数据卷失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"创建数据卷失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'创建数据卷失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def inspect(self, request, server_pk=None, pk=None):
        """获取数据卷详情"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.inspect_volume(pk)

            if result['success']:
                return Response({
                    'success': True,
                    'volume': result['data']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取数据卷详情失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取数据卷详情失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取数据卷详情失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def remove(self, request, server_pk=None, pk=None):
        """删除数据卷"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            force = request.data.get('force', False)
            result = docker_service.remove_volume(pk, force)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '删除数据卷失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"删除数据卷失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'删除数据卷失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['post'], url_path='cleanup')
    def prune_volumes_action(self, request, server_pk=None):
        """清理未使用的数据卷"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.prune_volumes()

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message'],
                    'deleted_volumes': result.get('deleted_volumes', []),
                    'space_reclaimed': result.get('space_reclaimed', 0)
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '清理数据卷失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"清理数据卷失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'清理数据卷失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path='inspect')
    def inspect(self, request, server_pk=None, pk=None):
        """获取网络详情"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            result = docker_service.inspect_network(pk)

            if result['success']:
                return Response({
                    'success': True,
                    'network': result['network']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取网络详情失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取网络详情失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取网络详情失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['post'])
    def build(self, request, server_pk=None):
        """构建镜像"""
        try:
            logger.info(f"构建镜像请求: server_pk={server_pk}")
            logger.info(f"请求数据: {request.data}")

            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            dockerfile_content = request.data.get('dockerfile_content')
            image_name = request.data.get('image_name')
            uploaded_files = request.data.get('uploaded_files', {})

            logger.info(f"Dockerfile内容长度: {len(dockerfile_content) if dockerfile_content else 0}")
            logger.info(f"镜像名称: {image_name}")
            logger.info(f"上传文件数量: {len(uploaded_files)}")

            if not image_name:
                return Response({
                    'success': False,
                    'message': '镜像名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            if not dockerfile_content:
                return Response({
                    'success': False,
                    'message': 'Dockerfile内容不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 使用DockerService的新方法来构建镜像
            result = docker_service.build_image_from_content(dockerfile_content, image_name, uploaded_files)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '构建镜像失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            logger.error(f"Docker服务器不存在: server_pk={server_pk}")
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            import traceback
            logger.error(f"构建镜像失败: {str(e)}")
            logger.error(f"错误详情: {traceback.format_exc()}")
            return Response({
                'success': False,
                'message': f'构建镜像失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



    @action(detail=False, methods=['post'], url_path='prune')
    def prune_images_action(self, request, server_pk=None):
        """清理镜像"""
        try:
            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            dangling_only = request.data.get('dangling_only', True)
            result = docker_service.prune_images(dangling_only=dangling_only)

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '清理镜像失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"清理镜像失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'清理镜像失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def run(self, request, server_pk=None, pk=None):
        """从镜像运行容器"""
        try:
            image_id = decode_image_id(pk)

            docker_server = DockerServer.objects.get(pk=server_pk, is_active=True)
            docker_service = DockerService(docker_server)

            container_name = request.data.get('container_name')
            ports = request.data.get('ports', [])
            volumes = request.data.get('volumes', [])
            env_vars = request.data.get('env_vars', {})
            command = request.data.get('command')

            # 获取额外参数
            args = request.data.get('args')
            restart_policy = request.data.get('restart_policy', 'no')
            auto_remove = request.data.get('auto_remove', False)
            privileged = request.data.get('privileged', False)
            user = request.data.get('user')
            working_dir = request.data.get('working_dir')
            hostname = request.data.get('hostname')
            network_mode = request.data.get('network_mode', 'default')
            memory_limit = request.data.get('memory_limit')
            cpu_limit = request.data.get('cpu_limit')

            result = docker_service.run_container_from_image(
                image_name=image_id,
                container_name=container_name,
                ports=ports,
                volumes=volumes,
                env_vars=env_vars,
                command=command,
                args=args,
                restart_policy=restart_policy,
                auto_remove=auto_remove,
                privileged=privileged,
                user=user,
                working_dir=working_dir,
                hostname=hostname,
                network_mode=network_mode,
                memory_limit=memory_limit,
                cpu_limit=cpu_limit
            )

            if result['success']:
                return Response({
                    'success': True,
                    'message': result['message'],
                    'container_id': result.get('container_id')
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '从镜像运行容器失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Docker服务器不存在或未启用'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"从镜像运行容器失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'从镜像运行容器失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class DockerImageDownloadView(View):
    """Docker镜像下载视图"""

    def get(self, request, filename):
        """下载镜像文件"""
        try:
            import tempfile
            import os

            temp_dir = tempfile.gettempdir()
            file_path = os.path.join(temp_dir, filename)

            if not os.path.exists(file_path):
                raise Http404("文件不存在")

            # 返回文件响应
            response = FileResponse(
                open(file_path, 'rb'),
                as_attachment=True,
                filename=filename
            )

            # 设置清理任务（可选，在下载完成后删除临时文件）
            # 这里可以添加异步任务来清理临时文件

            return response

        except Exception as e:
            logger.error(f"下载文件失败: {str(e)}")
            raise Http404("下载失败")


class DockerRegistryViewSet(viewsets.ModelViewSet):
    """Docker镜像仓库管理ViewSet"""
    queryset = DockerRegistry.objects.all()
    permission_classes = [IsAuthenticated]

    def get_serializer_class(self):
        if self.action == 'list':
            return DockerRegistryListSerializer
        return DockerRegistrySerializer

    @action(detail=True, methods=['post'])
    def test_connection(self, request, pk=None):
        """测试仓库连接"""
        try:
            registry = self.get_object()

            if registry.registry_type == 'harbor':
                # 使用Harbor API测试连接
                harbor_service = HarborAPIService(
                    harbor_url=registry.url,
                    auth_type=registry.auth_type,
                    username=registry.username,
                    password=registry.password,
                    robot_token=registry.robot_token
                )

                result = harbor_service.test_connection()

                if result['success']:
                    registry.connection_status = 'connected'
                    registry.last_check_time = timezone.now()
                    registry.save()

                    return Response({
                        'success': True,
                        'message': f'{registry.name} 连接测试成功',
                        'data': result.get('data', {})
                    })
                else:
                    registry.connection_status = 'disconnected'
                    registry.last_check_time = timezone.now()
                    registry.save()

                    return Response({
                        'success': False,
                        'message': f'{registry.name} 连接测试失败: {result.get("error", "未知错误")}'
                    }, status=status.HTTP_400_BAD_REQUEST)
            else:
                # 其他类型仓库的连接测试逻辑
                return Response({
                    'success': False,
                    'message': f'暂不支持 {registry.registry_type} 类型仓库的连接测试'
                }, status=status.HTTP_400_BAD_REQUEST)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"测试仓库连接失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'测试连接失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def sync_repositories(self, request, pk=None):
        """同步仓库数据"""
        try:
            registry = self.get_object()

            if registry.registry_type == 'harbor':
                # 使用Harbor API同步项目和仓库数据
                harbor_service = HarborAPIService(
                    harbor_url=registry.url,
                    auth_type=registry.auth_type,
                    username=registry.username,
                    password=registry.password,
                    robot_token=registry.robot_token
                )

                # 获取项目列表来更新仓库数量
                result = harbor_service.get_projects()

                if result['success']:
                    projects = result['data']
                    total_repositories = 0

                    # 统计所有项目的仓库数量
                    for project in projects:
                        repo_result = harbor_service.get_repositories(project['name'])
                        if repo_result['success']:
                            total_repositories += len(repo_result['data'])

                    # 更新仓库信息
                    registry.repositories_count = total_repositories
                    registry.last_sync_time = timezone.now()
                    registry.connection_status = 'connected'
                    registry.save()

                    return Response({
                        'success': True,
                        'message': f'{registry.name} 同步成功，共发现 {total_repositories} 个仓库',
                        'data': {
                            'repositories_count': total_repositories,
                            'projects_count': len(projects)
                        }
                    })
                else:
                    return Response({
                        'success': False,
                        'message': f'{registry.name} 同步失败: {result.get("error", "未知错误")}'
                    }, status=status.HTTP_400_BAD_REQUEST)
            else:
                # 其他类型仓库的同步逻辑
                return Response({
                    'success': False,
                    'message': f'暂不支持 {registry.registry_type} 类型仓库的同步'
                }, status=status.HTTP_400_BAD_REQUEST)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"同步仓库失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'同步失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def projects(self, request, pk=None):
        """获取Harbor项目列表"""
        try:
            registry = DockerRegistry.objects.get(pk=pk)

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持项目管理'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            page = int(request.query_params.get('page', 1))
            page_size = int(request.query_params.get('page_size', 10))
            name = request.query_params.get('name', '')

            result = harbor_service.get_projects(page=page, page_size=page_size, name=name)

            if result['success']:
                return Response({
                    'success': True,
                    'data': result['data']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取项目列表失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取Harbor项目列表失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取项目列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='create_project')
    def create_project(self, request, pk=None):
        """创建Harbor项目"""
        try:
            registry = DockerRegistry.objects.get(pk=pk)

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持项目创建'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            project_data = request.data
            result = harbor_service.create_project(project_data)

            if result['success']:
                return Response({
                    'success': True,
                    'message': '项目创建成功',
                    'data': result.get('data', {})
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '创建项目失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"创建Harbor项目失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'创建项目失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='update_project')
    def update_project(self, request, pk=None):
        """更新Harbor项目"""
        try:
            registry = DockerRegistry.objects.get(pk=pk)

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持项目更新'
                }, status=status.HTTP_400_BAD_REQUEST)

            project_name = request.data.get('project_name')
            if not project_name:
                return Response({
                    'success': False,
                    'message': '项目名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            # 构建更新数据 - Harbor API需要把public放在metadata中
            update_data = {}
            metadata = {}

            if 'public' in request.data:
                metadata['public'] = str(request.data['public']).lower()

            if 'metadata' in request.data and 'description' in request.data['metadata']:
                metadata['description'] = request.data['metadata']['description']

            if metadata:
                update_data['metadata'] = metadata

            result = harbor_service.update_project(project_name, update_data)

            if result['success']:
                return Response({
                    'success': True,
                    'message': f'项目 {project_name} 更新成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '更新项目失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"更新Harbor项目失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'更新项目失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='delete_project')
    def delete_project(self, request, pk=None):
        """删除Harbor项目"""
        try:
            registry = DockerRegistry.objects.get(pk=pk)

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持项目删除'
                }, status=status.HTTP_400_BAD_REQUEST)

            project_name = request.data.get('project_name')
            if not project_name:
                return Response({
                    'success': False,
                    'message': '项目名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            result = harbor_service.delete_project(project_name)

            if result['success']:
                return Response({
                    'success': True,
                    'message': f'项目 {project_name} 删除成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '删除项目失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"删除Harbor项目失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'删除项目失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path='repositories')
    def get_repositories(self, request, pk=None):
        """获取Harbor项目下的仓库列表"""
        try:
            registry = DockerRegistry.objects.get(pk=pk)

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持仓库管理'
                }, status=status.HTTP_400_BAD_REQUEST)

            project_name = request.query_params.get('project_name')
            if not project_name:
                return Response({
                    'success': False,
                    'message': '项目名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            page = int(request.query_params.get('page', 1))
            page_size = int(request.query_params.get('page_size', 10))

            result = harbor_service.get_repositories(project_name, page=page, page_size=page_size)

            if result['success']:
                return Response({
                    'success': True,
                    'data': result['data']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取仓库列表失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取Harbor仓库列表失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取仓库列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path='artifacts')
    def get_artifacts(self, request, pk=None):
        """获取Harbor仓库下的镜像列表"""
        try:
            registry = DockerRegistry.objects.get(pk=pk)

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持镜像管理'
                }, status=status.HTTP_400_BAD_REQUEST)

            project_name = request.query_params.get('project_name')
            repository_name = request.query_params.get('repository_name')

            if not project_name or not repository_name:
                return Response({
                    'success': False,
                    'message': '项目名称和仓库名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            page = int(request.query_params.get('page', 1))
            page_size = int(request.query_params.get('page_size', 10))

            result = harbor_service.get_artifacts(project_name, repository_name, page=page, page_size=page_size)

            if result['success']:
                return Response({
                    'success': True,
                    'data': result['data']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取镜像列表失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取Harbor镜像列表失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取镜像列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='delete_artifact')
    def delete_artifact(self, request, pk=None):
        """删除Harbor镜像"""
        print(f"🔥 收到删除请求: registry_id={pk}, data={request.data}")
        logger.info(f"收到删除请求: registry_id={pk}, data={request.data}")
        try:
            registry = DockerRegistry.objects.get(pk=pk)

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持镜像删除'
                }, status=status.HTTP_400_BAD_REQUEST)

            project_name = request.data.get('project_name')
            repository_name = request.data.get('repository_name')
            reference = request.data.get('reference')

            if not all([project_name, repository_name, reference]):
                return Response({
                    'success': False,
                    'message': '项目名称、仓库名称和镜像引用不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            # 处理repository_name格式 - 移除项目名称前缀
            if repository_name.startswith(f"{project_name}/"):
                clean_repository_name = repository_name[len(f"{project_name}/"):]
            else:
                clean_repository_name = repository_name

            result = harbor_service.delete_artifact(project_name, clean_repository_name, reference)

            if result['success']:
                return Response({
                    'success': True,
                    'message': f'镜像 {repository_name}:{reference} 删除成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '删除镜像失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            print(f"🔥 删除镜像异常: {str(e)}")
            import traceback
            print(f"🔥 异常堆栈: {traceback.format_exc()}")
            logger.error(f"删除Harbor镜像失败: {str(e)}", exc_info=True)
            return Response({
                'success': False,
                'message': f'删除镜像失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='scan_artifact')
    def scan_artifact(self, request, pk=None):
        """触发Harbor镜像漏洞扫描"""
        logger.info(f"收到扫描请求: registry_id={pk}, data={request.data}")
        try:
            registry = DockerRegistry.objects.get(pk=pk)
            logger.info(f"找到仓库: {registry.name}, type={registry.registry_type}")

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持漏洞扫描'
                }, status=status.HTTP_400_BAD_REQUEST)

            project_name = request.data.get('project_name')
            repository_name = request.data.get('repository_name')
            reference = request.data.get('reference')

            if not all([project_name, repository_name, reference]):
                return Response({
                    'success': False,
                    'message': '项目名称、仓库名称和镜像引用不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            logger.info(f"创建Harbor服务: url={registry.url}, auth_type={registry.auth_type}")
            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            # 处理repository_name格式 - 移除项目名称前缀
            if repository_name.startswith(f"{project_name}/"):
                clean_repository_name = repository_name[len(f"{project_name}/"):]
            else:
                clean_repository_name = repository_name

            logger.info(f"开始扫描镜像: {project_name}/{clean_repository_name}:{reference}")
            result = harbor_service.scan_artifact(project_name, clean_repository_name, reference)
            logger.info(f"Harbor扫描API响应: {result}")

            if result['success']:
                return Response({
                    'success': True,
                    'message': f'镜像 {clean_repository_name}:{reference} 扫描已启动'
                })
            else:
                error_msg = result.get('error', '启动扫描失败')

                # 如果包含扫描器相关错误，提供详细说明
                if ('no available scanner' in str(error_msg) or
                    'no scanner is configured' in str(error_msg) or
                    'PRECONDITION' in str(error_msg)):

                    error_msg = ('Harbor扫描器未配置。请按以下步骤配置：\n'
                               '1. 登录Harbor Web界面 (http://10.0.0.52)\n'
                               '2. 进入 Administration → Interrogation Services\n'
                               '3. 点击 "NEW SCANNER" 添加Trivy扫描器\n'
                               '4. 配置信息：\n'
                               '   - Name: Trivy\n'
                               '   - Endpoint URL: http://trivy-adapter:8080\n'
                               '   - 其他选项保持默认\n'
                               '5. 保存并设为默认扫描器')

                return Response({
                    'success': False,
                    'message': error_msg
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"启动Harbor镜像扫描失败: {str(e)}")
            error_msg = str(e)

            # 检查是否是扫描器配置问题
            if ('no available scanner' in error_msg or
                'no scanner is configured' in error_msg or
                'PRECONDITION' in error_msg):

                error_msg = ('Harbor扫描器未配置。请按以下步骤配置：\n'
                           '1. 登录Harbor Web界面 (http://10.0.0.52)\n'
                           '2. 进入 Administration → Interrogation Services\n'
                           '3. 点击 "NEW SCANNER" 添加Trivy扫描器\n'
                           '4. 配置信息：\n'
                           '   - Name: Trivy\n'
                           '   - Endpoint URL: http://trivy-adapter:8080\n'
                           '   - 其他选项保持默认\n'
                           '5. 保存并设为默认扫描器')

            return Response({
                'success': False,
                'message': error_msg
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path='vulnerabilities')
    def get_vulnerabilities(self, request, pk=None):
        """获取Harbor镜像漏洞信息"""
        try:
            registry = DockerRegistry.objects.get(pk=pk)

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor类型仓库支持漏洞扫描'
                }, status=status.HTTP_400_BAD_REQUEST)

            project_name = request.query_params.get('project_name')
            repository_name = request.query_params.get('repository_name')
            reference = request.query_params.get('reference')

            if not all([project_name, repository_name, reference]):
                return Response({
                    'success': False,
                    'message': '项目名称、仓库名称和镜像引用不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            # 处理repository_name格式 - 移除项目名称前缀
            if repository_name.startswith(f"{project_name}/"):
                clean_repository_name = repository_name[len(f"{project_name}/"):]
            else:
                clean_repository_name = repository_name

            # 获取扫描概览
            overview_result = harbor_service.get_scan_overview(project_name, clean_repository_name, reference)

            # 获取详细漏洞信息
            vuln_result = harbor_service.get_vulnerabilities(project_name, clean_repository_name, reference)

            if overview_result['success'] and vuln_result['success']:
                # 解析扫描状态和漏洞统计
                artifact_data = overview_result.get('data', {})
                scan_overview = artifact_data.get('scan_overview', {})

                # 解析漏洞详情
                vuln_data = vuln_result.get('data', {})

                return Response({
                    'success': True,
                    'data': {
                        'scan_overview': scan_overview,
                        'vulnerabilities': vuln_data
                    }
                })
            else:
                error_msg = overview_result.get('error') or vuln_result.get('error') or '获取漏洞信息失败'
                return Response({
                    'success': False,
                    'message': error_msg
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取Harbor镜像漏洞信息失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取漏洞信息失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path='audit-logs')
    def audit_logs(self, request, pk=None):
        """获取Harbor审计日志"""
        try:
            registry = self.get_object()

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor仓库支持审计日志功能'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            # 获取查询参数
            page = int(request.query_params.get('page', 1))
            page_size = int(request.query_params.get('page_size', 20))
            username = request.query_params.get('username', '')
            operation = request.query_params.get('operation', '')
            start_time = request.query_params.get('start_time', '')
            end_time = request.query_params.get('end_time', '')

            result = harbor_service.get_audit_logs(
                page=page,
                page_size=page_size,
                username=username,
                operation=operation,
                start_time=start_time,
                end_time=end_time
            )

            if result['success']:
                return Response({
                    'success': True,
                    'data': result['data']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取审计日志失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取Harbor审计日志失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取审计日志失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path='audit-log-statistics')
    def audit_log_statistics(self, request, pk=None):
        """获取Harbor审计日志统计信息"""
        try:
            registry = self.get_object()

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor仓库支持审计日志功能'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            result = harbor_service.get_audit_log_statistics()

            if result['success']:
                return Response({
                    'success': True,
                    'data': result['data']
                })
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '获取审计日志统计失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"获取Harbor审计日志统计失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取审计日志统计失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='export-audit-logs')
    def export_audit_logs(self, request, pk=None):
        """导出Harbor审计日志"""
        try:
            registry = self.get_object()

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor仓库支持审计日志功能'
                }, status=status.HTTP_400_BAD_REQUEST)

            harbor_service = HarborAPIService(
                harbor_url=registry.url,
                auth_type=registry.auth_type,
                username=registry.username,
                password=registry.password,
                robot_token=registry.robot_token
            )

            # 获取所有日志数据用于导出
            result = harbor_service.get_audit_logs(page=1, page_size=10000)

            if result['success']:
                from django.http import HttpResponse
                import json
                from datetime import datetime

                # 生成导出文件名
                timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
                filename = f'harbor_audit_logs_{registry.name}_{timestamp}.json'

                # 创建响应
                response = HttpResponse(
                    json.dumps(result['data'], indent=2, ensure_ascii=False),
                    content_type='application/json'
                )
                response['Content-Disposition'] = f'attachment; filename="{filename}"'

                return response
            else:
                return Response({
                    'success': False,
                    'message': result.get('error', '导出审计日志失败')
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"导出Harbor审计日志失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'导出审计日志失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='clear-audit-logs')
    def clear_audit_logs(self, request, pk=None):
        """清理Harbor审计日志"""
        try:
            registry = self.get_object()

            if registry.registry_type != 'harbor':
                return Response({
                    'success': False,
                    'message': '只有Harbor仓库支持审计日志功能'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 获取清理参数
            days = request.data.get('days', 30)  # 默认清理30天前的日志

            # 注意：Harbor API通常不支持直接删除审计日志
            # 这里返回一个提示信息
            return Response({
                'success': True,
                'message': f'Harbor审计日志清理功能需要在Harbor管理界面中进行配置，建议保留{days}天内的日志记录'
            })

        except DockerRegistry.DoesNotExist:
            return Response({
                'success': False,
                'message': '镜像仓库不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"清理Harbor审计日志失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'清理审计日志失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
